import java.util.ArrayList;
import java.util.HashSet;


public class Board 
{
	private Tile[][] _letters;
	private String[][] _stringMatrix;
	private int _rowLen;
	
	public Board(int numTiles, char[] alphabet) throws Exception
	{		
		if(Math.sqrt((double) numTiles) - (int) Math.sqrt((double) numTiles) != 0)
		{
			throw new Exception();
		}
		
		_rowLen = (int) Math.sqrt((double) numTiles);
		
		_letters = new Tile[_rowLen][_rowLen];
		
		for(int i = 0; i < _rowLen; i ++)
		{
			for(int j = 0; j < _rowLen; j++)
			{
				_letters[i][j] = new Tile(alphabet);
			}
		}
		
	}
	
	public boolean doesExist(String word)
	{
		boolean isPresent = false;
		
		ArrayList<int[]> startCoordinates = new ArrayList<int[]>();
		
		for(int i = 0; i < _rowLen; i++)
		{
			for(int j = 0; j < _rowLen; j++)
			{
				if(_letters[i][j].getLetter() == word.charAt(0))
				{
					int[] coordinates = new int[] {i, j};
					startCoordinates.add(coordinates);
				}
			}
		}
		
		
		for(int i = 0; i < startCoordinates.size() && !isPresent; i ++)
		{
			if(word.length() > 1)
			{
				isPresent = isThere(startCoordinates.get(i)[0], startCoordinates.get(i)[1], word, 1);
			}
			else
			{
				isPresent = true;
			}
		}
		
		return isPresent;
	}
	
	public Tile getTile(int x, int y)
	{
		return _letters[x][y];
	}
	
	public String[][] getTileString()
	{
		String[][] boardString = new String[_letters[0].length][_letters[0].length];
		
		for(int i = 0; i < _letters[0].length; i++)
		{
			for(int j = 0; j < _letters[0].length; j++)
			{
				boardString[i][j] = new Character(_letters[i][j].getLetter()).toString();
			}
		}

		return boardString;
	}
	
	private boolean isThere(int startX, int startY, String word, int index)
	{
		boolean exists = false;
		int counter = 0;
		ArrayList<int[]> validPoints = new ArrayList<int[]>();
		
		
		if(index == word.length())
		{
			exists = true;
		}
		else
		{
			if(startX+1 <_rowLen && _letters[startX + 1][startY].getLetter() == word.charAt(index))
			{
				validPoints.add(new int[] {startX + 1, startY});
			}
			if(startX-1 >= 0 && _letters[startX - 1][startY].getLetter() == word.charAt(index))
			{
				validPoints.add(new int[] {startX - 1, startY});
			}
			if(startY+1 <_rowLen && _letters[startX][startY + 1].getLetter() == word.charAt(index))
			{
				validPoints.add(new int[] {startX, startY + 1});
			}
			if(startY-1 >= 0 && _letters[startX][startY - 1].getLetter() == word.charAt(index))
			{
				validPoints.add(new int[] {startX, startY - 1});
			}
			if(startY-1 >= 0 && startX+1 <_rowLen && _letters[startX + 1][startY - 1].getLetter() == word.charAt(index))
			{
				validPoints.add(new int[] {startX + 1, startY - 1});
			}
			if(startY+1 <_rowLen && startX+1 <_rowLen && _letters[startX + 1][startY + 1].getLetter() == word.charAt(index))
			{
				validPoints.add(new int[] {startX + 1, startY + 1});
			}
			if(startY-1 >= 0 && startX-1 >= 0 && _letters[startX - 1][startY - 1].getLetter() == word.charAt(index))
			{
				validPoints.add(new int[] {startX - 1, startY - 1});
			}
			if(startY+1 <_rowLen && startX-1 >= 0 && _letters[startX - 1][startY + 1].getLetter() == word.charAt(index))
			{
				validPoints.add(new int[] {startX - 1, startY + 1});
			}
			
			while(!exists && counter < validPoints.size())
			{
				exists = isThere(validPoints.get(counter)[0], validPoints.get(counter)[1], word, index + 1);
				counter ++;
			}
			
		}
		
		
		if(!exists)
		{
			System.out.println(word);
			System.out.println(startX);
			System.out.println(startY);
			System.out.println(index);
			System.out.println(word.charAt(index));
			
		}
		
		return exists;
	}
	
}
